package com.snake.springboot.custom.service.impl.goods;

import com.github.pagehelper.Page;
import com.snake.springboot.custom.api.model.bill.BillPlaceOrderModel;
import com.snake.springboot.custom.api.model.common.CommonVal;
import com.snake.springboot.custom.api.model.goods.CustStryGoodsDetailModel;
import com.snake.springboot.custom.api.model.strategy.AuthBuyStrategyModel;
import com.snake.springboot.custom.api.request.bill.BillStrgGoodsPlaceDetailModel;
import com.snake.springboot.custom.api.request.bill.BillStrgGoodsPlaceModel;
import com.snake.springboot.custom.api.request.goods.CustStryGoodsQuery;
import com.snake.springboot.custom.api.request.page.PageQuery;
import com.snake.springboot.custom.api.response.bill.BillRsp;
import com.snake.springboot.custom.api.response.goods.CustStryGoodsRsp;
import com.snake.springboot.custom.api.response.goods.StrategyGoodsRsp;
import com.snake.springboot.custom.api.service.goods.CustStryGoodsDetailService;
import com.snake.springboot.custom.api.service.goods.CustStryGoodsService;
import com.snake.springboot.custom.api.service.goods.StrategyGoodsService;
import com.snake.springboot.custom.dao.mybatis.entity.goods.CustStryGoodsDO;
import com.snake.springboot.custom.dao.mybatis.entity.goods.CustStryGoodsDetailDO;
import com.snake.springboot.custom.dao.mybatis.mappers.goods.CustStryGoodsMapper;
import com.snake.springboot.custom.service.assemble.goods.CustStryGoodsAssemble;
import com.snake.springboot.custom.service.assemble.strategy.StrategyAssemble;
import com.snake.springboot.custom.service.port.adapter.event.AuthStryBuyEvent;
import com.snake.springboot.custom.service.port.adapter.event.BillPlaceOrderEvt;
import com.snake.springboot.custom.service.utils.PageUtils;
import org.snake.common.exception.OperationException;
import org.snake.common.result.ReturnList;
import org.snake.common.utils.ListUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class CustStryGoodsServiceImpl implements CustStryGoodsService{

    @Autowired
    private CustStryGoodsMapper custStryGoodsMapper;
    @Autowired
    private CustStryGoodsDetailService detailService;
    @Autowired
    private StrategyGoodsService goodsService;
    @Autowired
    private ApplicationContext applicationContext;

    @Override
    public ReturnList<CustStryGoodsRsp> queryCustStryGoodsList(PageQuery<CustStryGoodsQuery> params) {
        Page<Object> objects = PageUtils.forcePage(params.getPage());
        CustStryGoodsDO queryDO = CustStryGoodsAssemble.toGoodsDO(params.getParams());
        List<CustStryGoodsDO> dos = custStryGoodsMapper.queryList(queryDO);
        List<CustStryGoodsRsp> rspList = ListUtils.copy(dos, CustStryGoodsRsp.class);
        detailService.queryDetailList(rspList);
        return new ReturnList<>(rspList,objects.getTotal());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public BillRsp placeOrder(BillStrgGoodsPlaceModel model) {
        List<BillStrgGoodsPlaceDetailModel> detailList = model.getDetailList();
        //抓取数据
        List<StrategyGoodsRsp> details = goodsService.payDetail(detailList.stream().map(BillStrgGoodsPlaceDetailModel::getStrategyGoodsId).collect(Collectors.toList()));
        checkLimitBuy(model,details);
        BillPlaceOrderModel placeOrderModel = new BillPlaceOrderModel();
        List<CustStryGoodsDO> goodsDOS = new ArrayList<>(details.size());
        List<CustStryGoodsDetailModel> models = CustStryGoodsAssemble.toDetailList(model, details,placeOrderModel,goodsDOS);
        //保存订单数据
        custStryGoodsMapper.insertBatch(goodsDOS);
        // 保存明细数据
        detailService.insertBatch(models);
        //保存账单信息
        BillPlaceOrderEvt placeOrderEvt = new BillPlaceOrderEvt(this, placeOrderModel);
        applicationContext.publishEvent(placeOrderEvt);
        return placeOrderEvt.getResult();
    }

    @Override
    public void callback(String billId) {
        List<CustStryGoodsDetailDO> detailDOS = custStryGoodsMapper.queryDetailById(billId);
        List<AuthBuyStrategyModel> strategyModel = StrategyAssemble.toOpStrategyModel(detailDOS);
        AuthStryBuyEvent buyEvent = new AuthStryBuyEvent(this, strategyModel);
        applicationContext.publishEvent(buyEvent);
    }

    @Override
    public void ret(String billId) {
        List<CustStryGoodsDetailDO> detailDOS = custStryGoodsMapper.queryDetailById(billId);
        List<AuthBuyStrategyModel> strategyModel = StrategyAssemble.toOpStrategyModel(detailDOS);
        AuthStryBuyEvent buyEvent = new AuthStryBuyEvent(this, strategyModel);
        applicationContext.publishEvent(buyEvent);
    }

    /**
     * 限购校验
     * @param model
     * @param details
     */
    private void checkLimitBuy(BillStrgGoodsPlaceModel model, List<StrategyGoodsRsp> details) {
        for (StrategyGoodsRsp rsp : details) {
            if (CommonVal.Y.equals(rsp.getLimitBuy())) {
                for (BillStrgGoodsPlaceDetailModel detailModel : model.getDetailList()) {
                    if (rsp.getStrategyGoodsId().equals(detailModel.getStrategyGoodsId())) {
                        Integer buyCount = custStryGoodsMapper.queryBuyCount(detailModel.getStrategyGoodsId(), model.getCustomId());
                        int i = detailModel.getPlaceNum() + buyCount;
                        OperationException.checkIsTrue(i <= rsp.getBuyCount(), "商品[" + rsp.getGoodsName() + "]超出购买数量");
                    }
                }
            }
        }
    }



}
